/**
 * @param {number[]} nums
 * @param {number} limit
 * @return {number}
 */
var minMoves1 = function (nums, limit) {
  let start = 0,
    end = nums.length - 1
  let abss = []
  let obj = {}
  let maxSum = []

  let maxCount = 0
  let res = 0
  while (start < end) {
    let sum = nums[start] + nums[end]
    obj[sum] = obj[sum] || { count: 0, subs: [] }
    obj[sum].count += 1
    obj[sum].subs.push(start)

    // obj[sum] = obj[sum] || 0
    // obj[sum] += 1
    if (obj[sum].count > maxCount) {
      maxCount = obj[sum].count
      maxSum = [sum]
    } else if (obj[sum].count === maxCount) {
      maxSum.push(sum)
    }
    abss.push(sum)
    start += 1
    end -= 1
  }
  function getSum(maxSum) {
    let keys = Object.keys(obj)
    let res = 0
    keys.forEach(key => {
      let k = key - 0
      if (k !== maxSum) {
        obj[k].subs.forEach(idx => {
          if (
            (limit + Math.max(nums[idx], nums[nums.length - 1 - idx]) >=
              maxSum &&
              k < maxSum) ||
            (k > maxSum &&
              Math.min(nums[idx], nums[nums.length - 1 - idx]) + 1 <= maxSum)
          ) {
            res += 1
          } else {
            res += 2
          }
        })
      }
    })
    return res
  }
  if (Object.keys(obj).length !== 1) {
    res = nums.length
    // maxSum.forEach((item) => {
    Object.keys(obj).forEach(item => {
      res = Math.min(getSum(item - 0), res, nums.length / 2)
    })
  }
  return res
}

var minMoves2 = function (nums, limit) {
  let len = nums.length
  let res = len / 2
  let obj = {}
  for (let i = 0; i < len / 2; i++) {
    let sum = nums[i] + nums[len - 1 - i]
    if (obj[sum]) {
      continue
    }
    obj[sum] = true
    let count = 0
    for (let j = 0; j < len / 2; j++) {
      let tmpSum = nums[j] + nums[len - 1 - j]
      if (j == i || tmpSum === sum) {
        continue
      } else {
        if (
          (limit + Math.max(nums[j], nums[nums.length - 1 - j]) >= sum &&
            tmpSum < sum) ||
          (tmpSum > sum &&
            Math.min(nums[j], nums[nums.length - 1 - j]) + 1 <= sum)
        ) {
          count += 1
        } else {
          count += 2
        }
      }
      if (count >= res) {
        break
      }
    }
    res = Math.min(res, count)
  }
  return res
}

var minMoves = function (nums, limit) {
  let diff = Array(2 * limit + 2).fill(0) //数组li存的是每个可能的和的转化次数,用差分数组diff存储 差分数组  https://cloud.tencent.com/developer/article/1629357
  for (let i = 0; i < nums.length / 2; i++) {
    let A = nums[i]
    let B = nums[nums.length - 1 - i]
    //初始所有可能的和需要转换2次
    let l = 2
    let r = 2 * limit
    diff[l] += 2
    diff[r + 1] -= 2

    // [1 + min(A, B), limit + max(A, B)] 范围内的值只需要转换一次  即-1
    l = 1 + Math.min(A, B)
    r = limit + Math.max(A, B)
    diff[l] += -1
    diff[r + 1] -= -1

    // [A + B] 的值不需要转换  再 -1
    l = A + B
    r = A + B
    diff[l] += -1
    diff[r + 1] -= -1
    console.log('diff: ', diff)
  }
  // 依次求和，得到 最终互补的数字和 i 的时候，需要的操作数 sum
  // 取最小值
  let res = nums.length,
    sum = 0
  for (let i = 2; i <= 2 * limit; i++) {
    sum += diff[i]
    if (sum < res) res = sum
  }
  return res
}
let nums = [1, 4, 4, 3]

let limit = 4
// limit = 59832

console.log(minMoves(nums, limit))
// console.log(minMoves2(nums, limit))
// console.log(minMoves1(nums, limit))
